/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * UploadPhotobucket.java
 *
 * Created on Oct 26, 2010, 2:09:51 PM
 */
package uploadphotobucket;

import com.photobucket.api.core.FileUploadProgressEvent;
import com.photobucket.api.core.IFileUploadProgressEventListener;
import com.photobucket.api.core.PhotobucketAPI;
import com.photobucket.api.rest.RESTfulResponse;
import java.awt.Cursor;
import java.awt.Font;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Vector;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableModel;
import utils.Utils;
import utils.ImageFilter;
import utils.ImagePreview;
import utils.TextFilter;

/**
 *
 * @author banhbaochay
 */
public class UploadPhotobucket extends javax.swing.JFrame {

    /** Creates new form UploadPhotobucket */
    public UploadPhotobucket() {
        try {
            for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equalsIgnoreCase(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (Exception e) {
        }

        initData();
        initComponents();
        Font fontArea = resultArea.getFont();
        resultArea.setFont(new Font(fontArea.getFontName(), fontArea.getStyle(), 14));
    }

    private void initData() {
        currentPath = System.getProperty("user.home");
        oauth_consumer = ResourceBundle.getBundle("consumer").getString("oauth.consumer");
        oauth_consumer_key = ResourceBundle.getBundle("consumer").getString("oauth.consumer.key");
        consumerMap = null;
        userMap = null;

        albumsMap = new HashMap<String, HashMap<String, String>>();
        comboBoxModel = new DefaultComboBoxModel();
        dataUpload = new Vector();
        columnUpload = new Vector();
        columnUpload.add("File to upload");
        columnUpload.add("Link URL");
        columnUpload.add("Link Blog-Forum");
        columnUpload.add("Status");
        uploadTableModel = new DefaultTableModel(dataUpload, columnUpload);

        if (System.getProperty("os.name").startsWith("Windows")) {
            browser = "windows";
        } else {
            browser = Utils.getBrowsePathLinux();
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jTabbedPane1 = new javax.swing.JTabbedPane();
        loginPanel = new javax.swing.JPanel();
        jPanel1 = new javax.swing.JPanel();
        getReqButton = new javax.swing.JButton();
        jLabel2 = new javax.swing.JLabel();
        goButton = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        resultArea = new javax.swing.JTextArea();
        accessButton = new javax.swing.JButton();
        uploadPanel = new javax.swing.JPanel();
        jPanel2 = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        uploadTable = new javax.swing.JTable();
        uploadButton = new javax.swing.JButton();
        clearButton = new javax.swing.JButton();
        removeButton = new javax.swing.JButton();
        addButton = new javax.swing.JButton();
        showImageButton = new javax.swing.JButton();
        copyLinkURLButton = new javax.swing.JButton();
        jLabel26 = new javax.swing.JLabel();
        albumComboBox = new javax.swing.JComboBox();
        jLabel27 = new javax.swing.JLabel();
        numberTextField = new javax.swing.JTextField();
        copyLinkBlogButton = new javax.swing.JButton();
        saveButton = new javax.swing.JButton();
        howToUsePanel = new javax.swing.JPanel();
        jLabel9 = new javax.swing.JLabel();
        jLabel10 = new javax.swing.JLabel();
        jLabel11 = new javax.swing.JLabel();
        jLabel12 = new javax.swing.JLabel();
        jLabel13 = new javax.swing.JLabel();
        jLabel14 = new javax.swing.JLabel();
        jLabel15 = new javax.swing.JLabel();
        jLabel16 = new javax.swing.JLabel();
        jLabel17 = new javax.swing.JLabel();
        jLabel18 = new javax.swing.JLabel();
        jLabel19 = new javax.swing.JLabel();
        jLabel20 = new javax.swing.JLabel();
        jLabel21 = new javax.swing.JLabel();
        jLabel22 = new javax.swing.JLabel();
        jLabel23 = new javax.swing.JLabel();
        jLabel24 = new javax.swing.JLabel();
        jLabel25 = new javax.swing.JLabel();
        aboutPanel = new javax.swing.JPanel();
        jLabel3 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        jLabel7 = new javax.swing.JLabel();
        jLabel8 = new javax.swing.JLabel();
        jLabel28 = new javax.swing.JLabel();
        jLabel29 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Upload Photobucket");

        jPanel1.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        getReqButton.setText("Get Request");
        getReqButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getReqButtonActionPerformed(evt);
            }
        });
        jPanel1.add(getReqButton, new org.netbeans.lib.awtextra.AbsoluteConstraints(140, 20, -1, -1));

        jLabel2.setText("Result From Web");
        jPanel1.add(jLabel2, new org.netbeans.lib.awtextra.AbsoluteConstraints(40, 60, -1, -1));

        goButton.setText("Go to Accept's page");
        goButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                goButtonActionPerformed(evt);
            }
        });
        jPanel1.add(goButton, new org.netbeans.lib.awtextra.AbsoluteConstraints(190, 260, -1, -1));

        resultArea.setColumns(20);
        resultArea.setLineWrap(true);
        resultArea.setRows(5);
        resultArea.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                resultAreaMouseClicked(evt);
            }
        });
        jScrollPane1.setViewportView(resultArea);

        jPanel1.add(jScrollPane1, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 90, 500, 110));

        accessButton.setText("Access Account");
        accessButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                accessButtonActionPerformed(evt);
            }
        });
        jPanel1.add(accessButton, new org.netbeans.lib.awtextra.AbsoluteConstraints(290, 20, -1, -1));

        loginPanel.add(jPanel1);

        jTabbedPane1.addTab("Log In", loginPanel);

        jPanel2.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        uploadTable.setModel(uploadTableModel);
        jScrollPane2.setViewportView(uploadTable);

        jPanel2.add(jScrollPane2, new org.netbeans.lib.awtextra.AbsoluteConstraints(10, 82, 540, 280));

        uploadButton.setText("Upload");
        uploadButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                uploadButtonActionPerformed(evt);
            }
        });
        jPanel2.add(uploadButton, new org.netbeans.lib.awtextra.AbsoluteConstraints(600, 290, 90, -1));

        clearButton.setText("Clear all");
        clearButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                clearButtonActionPerformed(evt);
            }
        });
        jPanel2.add(clearButton, new org.netbeans.lib.awtextra.AbsoluteConstraints(600, 230, 90, -1));

        removeButton.setText("Remove");
        removeButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeButtonActionPerformed(evt);
            }
        });
        jPanel2.add(removeButton, new org.netbeans.lib.awtextra.AbsoluteConstraints(600, 170, 90, -1));

        addButton.setText("Add");
        addButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addButtonActionPerformed(evt);
            }
        });
        jPanel2.add(addButton, new org.netbeans.lib.awtextra.AbsoluteConstraints(600, 110, 90, -1));

        showImageButton.setText("Show Image");
        showImageButton.setToolTipText("Show Image in your browser");
        showImageButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                showImageButtonActionPerformed(evt);
            }
        });
        jPanel2.add(showImageButton, new org.netbeans.lib.awtextra.AbsoluteConstraints(80, 400, -1, -1));

        copyLinkURLButton.setText("Copy Link URL");
        copyLinkURLButton.setToolTipText("Copy link in cell you selected to clipboard");
        copyLinkURLButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                copyLinkURLButtonActionPerformed(evt);
            }
        });
        jPanel2.add(copyLinkURLButton, new org.netbeans.lib.awtextra.AbsoluteConstraints(280, 400, -1, -1));

        jLabel26.setText("Select Album");
        jPanel2.add(jLabel26, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 30, -1, -1));

        albumComboBox.setModel(comboBoxModel);
        albumComboBox.setToolTipText("Choose album for uploading images");
        albumComboBox.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                albumComboBoxItemStateChanged(evt);
            }
        });
        jPanel2.add(albumComboBox, new org.netbeans.lib.awtextra.AbsoluteConstraints(110, 30, 160, -1));

        jLabel27.setText("Number photos");
        jPanel2.add(jLabel27, new org.netbeans.lib.awtextra.AbsoluteConstraints(300, 30, -1, -1));

        numberTextField.setEditable(false);
        numberTextField.setToolTipText("Number photos in selected album");
        jPanel2.add(numberTextField, new org.netbeans.lib.awtextra.AbsoluteConstraints(410, 30, 140, -1));

        copyLinkBlogButton.setText("Copy Link Blog");
        copyLinkBlogButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                copyLinkBlogButtonActionPerformed(evt);
            }
        });
        jPanel2.add(copyLinkBlogButton, new org.netbeans.lib.awtextra.AbsoluteConstraints(470, 400, -1, -1));

        saveButton.setText("Save ");
        saveButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveButtonActionPerformed(evt);
            }
        });
        jPanel2.add(saveButton, new org.netbeans.lib.awtextra.AbsoluteConstraints(280, 460, 110, -1));

        uploadPanel.add(jPanel2);

        jTabbedPane1.addTab("Upload", uploadPanel);

        jLabel9.setText("You should do follow steps for uploading images to photobucket.com");

        jLabel10.setText("1. Ask permission for access account photobucket");

        jLabel11.setText("- Click Get Request button. Then result from web 'll show format: http://...");

        jLabel12.setText("If not, please check your internet connection to photobucket.com");

        jLabel13.setText("- Click Go to Access's page button. You 'll see access's page in your browser");

        jLabel14.setText("If not, you can copy link in result from web and open in your browser.");

        jLabel15.setText("Then you type your account photobucket to accept permission");

        jLabel16.setText("2. Make program access to your account photobucket");

        jLabel17.setText("- Click Access Account button. If result from web display message done,");

        jLabel18.setText("you can upload to your account from now");

        jLabel19.setText("3. Upload images");

        jLabel20.setText("- Click Add button then choose one or multiple images from desktop.");

        jLabel21.setText("Your images 'll display in left table. You can add, remove, clear with");

        jLabel22.setText("Add, Remove, Clear button in right");

        jLabel23.setText("- After upload successful, you can select one or multiple images in bottom");

        jLabel24.setText("table and click Show Image button to show in your browser");

        jLabel25.setText("Note: You must ask permission and access account every program starts");

        javax.swing.GroupLayout howToUsePanelLayout = new javax.swing.GroupLayout(howToUsePanel);
        howToUsePanel.setLayout(howToUsePanelLayout);
        howToUsePanelLayout.setHorizontalGroup(
            howToUsePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, howToUsePanelLayout.createSequentialGroup()
                .addGap(120, 120, 120)
                .addGroup(howToUsePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, howToUsePanelLayout.createSequentialGroup()
                        .addGap(77, 77, 77)
                        .addComponent(jLabel12, javax.swing.GroupLayout.DEFAULT_SIZE, 495, Short.MAX_VALUE))
                    .addGroup(howToUsePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                        .addComponent(jLabel25, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addGroup(javax.swing.GroupLayout.Alignment.LEADING, howToUsePanelLayout.createSequentialGroup()
                            .addGap(79, 79, 79)
                            .addComponent(jLabel24, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addGroup(javax.swing.GroupLayout.Alignment.LEADING, howToUsePanelLayout.createSequentialGroup()
                            .addGap(77, 77, 77)
                            .addComponent(jLabel18, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addGroup(javax.swing.GroupLayout.Alignment.LEADING, howToUsePanelLayout.createSequentialGroup()
                            .addGap(53, 53, 53)
                            .addComponent(jLabel17, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addComponent(jLabel9, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 551, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGroup(javax.swing.GroupLayout.Alignment.LEADING, howToUsePanelLayout.createSequentialGroup()
                            .addGap(56, 56, 56)
                            .addGroup(howToUsePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(jLabel13, javax.swing.GroupLayout.PREFERRED_SIZE, 499, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(jLabel11, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                        .addGroup(javax.swing.GroupLayout.Alignment.LEADING, howToUsePanelLayout.createSequentialGroup()
                            .addGap(77, 77, 77)
                            .addGroup(howToUsePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(jLabel15, javax.swing.GroupLayout.DEFAULT_SIZE, 478, Short.MAX_VALUE)
                                .addComponent(jLabel14, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                        .addGroup(javax.swing.GroupLayout.Alignment.LEADING, howToUsePanelLayout.createSequentialGroup()
                            .addGap(29, 29, 29)
                            .addGroup(howToUsePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(jLabel16, javax.swing.GroupLayout.DEFAULT_SIZE, 526, Short.MAX_VALUE)
                                .addComponent(jLabel10, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(jLabel19, javax.swing.GroupLayout.DEFAULT_SIZE, 526, Short.MAX_VALUE)))
                        .addGroup(javax.swing.GroupLayout.Alignment.LEADING, howToUsePanelLayout.createSequentialGroup()
                            .addGap(79, 79, 79)
                            .addGroup(howToUsePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(jLabel22, javax.swing.GroupLayout.DEFAULT_SIZE, 476, Short.MAX_VALUE)
                                .addComponent(jLabel21, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                        .addGroup(javax.swing.GroupLayout.Alignment.LEADING, howToUsePanelLayout.createSequentialGroup()
                            .addGap(57, 57, 57)
                            .addGroup(howToUsePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(jLabel23, javax.swing.GroupLayout.DEFAULT_SIZE, 498, Short.MAX_VALUE)
                                .addComponent(jLabel20, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))))
                .addGap(123, 123, 123))
        );
        howToUsePanelLayout.setVerticalGroup(
            howToUsePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(howToUsePanelLayout.createSequentialGroup()
                .addGap(27, 27, 27)
                .addComponent(jLabel9)
                .addGap(18, 18, 18)
                .addComponent(jLabel10)
                .addGap(18, 18, 18)
                .addComponent(jLabel11)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jLabel12)
                .addGap(18, 18, 18)
                .addComponent(jLabel13)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jLabel14)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jLabel15)
                .addGap(18, 18, 18)
                .addComponent(jLabel16)
                .addGap(18, 18, 18)
                .addComponent(jLabel17)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jLabel18)
                .addGap(18, 18, 18)
                .addComponent(jLabel19)
                .addGap(18, 18, 18)
                .addComponent(jLabel20)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jLabel21)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jLabel22)
                .addGap(18, 18, 18)
                .addComponent(jLabel23)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jLabel24)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jLabel25)
                .addContainerGap(55, Short.MAX_VALUE))
        );

        jTabbedPane1.addTab("How to use", howToUsePanel);

        aboutPanel.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        jLabel3.setText("Author: Lê Anh Dũng");
        aboutPanel.add(jLabel3, new org.netbeans.lib.awtextra.AbsoluteConstraints(60, 100, -1, -1));

        jLabel4.setText("Nation: Việt Nam");
        aboutPanel.add(jLabel4, new org.netbeans.lib.awtextra.AbsoluteConstraints(60, 130, 131, -1));

        jLabel5.setText("Use Photobucket API from website: http://photobucket.com/developer/");
        aboutPanel.add(jLabel5, new org.netbeans.lib.awtextra.AbsoluteConstraints(60, 190, 470, -1));

        jLabel6.setText("Many thanks for people who develop API for Java");
        aboutPanel.add(jLabel6, new org.netbeans.lib.awtextra.AbsoluteConstraints(60, 220, -1, -1));

        jLabel7.setText("Email: anhdungle1986@gmail.com");
        aboutPanel.add(jLabel7, new org.netbeans.lib.awtextra.AbsoluteConstraints(60, 160, 220, -1));

        jLabel8.setText("Please feedback follow my email, thanks for using!");
        aboutPanel.add(jLabel8, new org.netbeans.lib.awtextra.AbsoluteConstraints(60, 270, 450, -1));

        jLabel28.setText("Program: Upload Image to Photobucket.com");
        aboutPanel.add(jLabel28, new org.netbeans.lib.awtextra.AbsoluteConstraints(60, 40, 460, -1));

        jLabel29.setText("Version: 0.4 - 11.26.2011");
        aboutPanel.add(jLabel29, new org.netbeans.lib.awtextra.AbsoluteConstraints(60, 70, 300, -1));

        jTabbedPane1.addTab("About", aboutPanel);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jTabbedPane1)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 604, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void getReqButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_getReqButtonActionPerformed
        // TODO add your handling code here:
        this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        resultArea.setText("");
        request();
        this.setCursor(null);
    }//GEN-LAST:event_getReqButtonActionPerformed

    private void accessButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_accessButtonActionPerformed
        // TODO add your handling code here:
        this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

//        Check condition for access
        if (consumerMap == null) {
            String error = "You have not permission to access to account.\nPlease"
                    + " read how-to-use and do it";
            JOptionPane.showMessageDialog(null, error, "Error",
                    JOptionPane.ERROR_MESSAGE);
        } else {
            access();
            if (userMap.get("oauth_token") != null) {
                resultArea.setText("Access account done!");
            } else {
                resultArea.setText("Access failed!");
                String error = "You have not permission to access to account.\n"
                        + "Please read how-to-use and do it";
                JOptionPane.showMessageDialog(null, error, "Error",
                        JOptionPane.ERROR_MESSAGE);
            }
        }

//        Map all albums in account to JComboBox
        albumsMap = Utils.getAlbumsMap(getAlbumInfo());
        Iterator<String> it = albumsMap.keySet().iterator();
        while (it.hasNext()) {
            comboBoxModel.addElement(it.next());
        }

        this.setCursor(null);
    }//GEN-LAST:event_accessButtonActionPerformed

    private void resultAreaMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_resultAreaMouseClicked
        // TODO add your handling code here:
        resultArea.selectAll();
        Utils.setClipboard(resultArea.getSelectedText());
    }//GEN-LAST:event_resultAreaMouseClicked

    private void uploadButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_uploadButtonActionPerformed
        // TODO add your handling code here:
        countSuccess = 0;
        if (consumerMap == null) {
            String error = "You have not permission access to account.\n"
                    + "Please read how-to-use and do it.";
            JOptionPane.showMessageDialog(null, error, "Error",
                    JOptionPane.ERROR_MESSAGE);
        } else if (userMap == null) {
            String error = "You need access to account before uploading images"
                    + "to photobucket\nPlease read how-to-use and do it";
            JOptionPane.showMessageDialog(null, error, "Error",
                    JOptionPane.ERROR_MESSAGE);
        } else {
            String albumName = (String) comboBoxModel.getSelectedItem();
            worker = new UploadWorker(albumName);
            worker.execute();
        }
    }//GEN-LAST:event_uploadButtonActionPerformed

    private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addButtonActionPerformed
        // TODO add your handling code here:
        JFileChooser fc = new JFileChooser();
        fc.setAccessory(new ImagePreview(fc));
        fc.setCurrentDirectory(new File(currentPath));
        fc.setFileFilter(new ImageFilter());
        fc.setMultiSelectionEnabled(true);
        fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
        int returnVal = fc.showOpenDialog(this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File[] files = fc.getSelectedFiles();
            File dir = fc.getCurrentDirectory();
            currentPath = dir.getPath();
            for (File file : files) {
                Vector tmp = new Vector();
                tmp.add(file);
                tmp.add("");
                tmp.add("");
                tmp.add("Waiting");
                uploadTableModel.addRow(tmp);
            }
        }
    }//GEN-LAST:event_addButtonActionPerformed

    private void removeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeButtonActionPerformed
        // TODO add your handling code here:
        int[] rows = uploadTable.getSelectedRows();
        for (int i = rows.length - 1; i >= 0; i--) {
            uploadTableModel.removeRow(rows[i]);
        }
    }//GEN-LAST:event_removeButtonActionPerformed

    private void clearButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearButtonActionPerformed
        // TODO add your handling code here:
        uploadTableModel.getDataVector().removeAllElements();
        uploadTableModel.fireTableDataChanged();
    }//GEN-LAST:event_clearButtonActionPerformed

    private void goButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_goButtonActionPerformed
        // TODO add your handling code here:
        this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        String url = resultArea.getText();
        try {
            if (browser == null) {
                Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler "
                        + url);
            } else {
                Runtime.getRuntime().exec(new String[]{browser, url});
            }
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(null, ex.getMessage(), "Error",
                    JOptionPane.ERROR_MESSAGE);
        }
        this.setCursor(null);
    }//GEN-LAST:event_goButtonActionPerformed

    private void showImageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showImageButtonActionPerformed
        // TODO add your handling code here:
        if (browser.equals("nobrowser")) {
            JOptionPane.showMessageDialog(null, "Can't find browser in your OS", "Error", JOptionPane.ERROR_MESSAGE);
        } else {
            int[] rowArray = uploadTable.getSelectedRows();
            if (rowArray.length > 0) {
                for (int row : rowArray) {
                    String status = (String) uploadTableModel.getValueAt(row, 3);

                    if (status.equals("Done")) {
                        try {
                            String url = (String) uploadTableModel.getValueAt(row, 1);
                            if (browser.equals("windows")) {
                                Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler "
                                        + url);
                            } else {
                                Runtime.getRuntime().exec(new String[]{browser, url});
                            }
                        } catch (IOException e) {
                            JOptionPane.showMessageDialog(null, e.getMessage(), "Error",
                                    JOptionPane.ERROR_MESSAGE);
                        }
                    } else {
                        String error = "Upload failed! Cannot show URL of file";
                        JOptionPane.showMessageDialog(null, error, "Error",
                                JOptionPane.ERROR_MESSAGE);
                    }
                }
            } else {
                String error = "No selected link to show image!";
                JOptionPane.showMessageDialog(null, error, "Information",
                        JOptionPane.INFORMATION_MESSAGE);
            }
        }
    }//GEN-LAST:event_showImageButtonActionPerformed

    private void copyLinkURLButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_copyLinkURLButtonActionPerformed
        // TODO add your handling code here:
        int[] rows = uploadTable.getSelectedRows();
        if (rows.length > 0) {
            String links = "";
            for (int row : rows) {
                String status = (String) uploadTableModel.getValueAt(row, 3);
                if (status.equals("Done")) {
                    links = links + (String) uploadTableModel.getValueAt(row, 1);
                }
            }
            String message = (links.equals("")) ? "All selected rows are failed upload"
                    : "Link url is copied to clipboard";
            Utils.setClipboard(links);
            JOptionPane.showMessageDialog(null, message, "Message",
                    JOptionPane.INFORMATION_MESSAGE);
        } else {
            // no selected row
            String message = "No link to copy.\nYou should select row before copying";
            JOptionPane.showMessageDialog(null, message, "Information",
                    JOptionPane.INFORMATION_MESSAGE);
        }
    }//GEN-LAST:event_copyLinkURLButtonActionPerformed

    private void albumComboBoxItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_albumComboBoxItemStateChanged
        // TODO add your handling code here:
        String albumName = (String) evt.getItem();
        String photo_count = ((HashMap<String, String>) albumsMap.get(albumName)).get("photo_count");
        numberTextField.setText(photo_count);
    }//GEN-LAST:event_albumComboBoxItemStateChanged

    private void copyLinkBlogButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_copyLinkBlogButtonActionPerformed
        // TODO add your handling code here:
        int[] rows = uploadTable.getSelectedRows();
        if (rows.length > 0) {
            String links = "";
            for (int row : rows) {
                String status = (String) uploadTableModel.getValueAt(row, 3);
                if (status.equals("Done")) {
                    links = links + (String) uploadTableModel.getValueAt(row, 2);
                }
            }
            Utils.setClipboard(links);
            String message = (links.equals("")) ? "All selected rows are failed upload"
                    : "Link blog-forum is copied to clipboard";
            JOptionPane.showMessageDialog(null, message, "Message",
                    JOptionPane.INFORMATION_MESSAGE);
        } else {
            // no selected row
            String message = "No link to copy.\nYou should select row before copying";
            JOptionPane.showMessageDialog(null, message, "Information",
                    JOptionPane.INFORMATION_MESSAGE);
        }
    }//GEN-LAST:event_copyLinkBlogButtonActionPerformed

    private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveButtonActionPerformed
        // TODO add your handling code here:
        ArrayList<String> urlList = getURLList();
        if (urlList.isEmpty()) {
            /* No line in uploadTable or no successful upload*/
            String message = "No data to save";
            JOptionPane.showMessageDialog(null, message, "Warning", JOptionPane.WARNING_MESSAGE);
        } else {
            JFileChooser fc = new JFileChooser();
            fc.setFileFilter(new TextFilter());
            fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
            int val = fc.showSaveDialog(null);
            if (val == JFileChooser.APPROVE_OPTION) {
                PrintWriter out = null;
                try {
                    File f = fc.getSelectedFile();
                    out = new PrintWriter(f);
                    for (String url : urlList) {
                        out.print(url);
                        out.print("\r\n");
                    }
                } catch (FileNotFoundException ex) {
                    JOptionPane.showMessageDialog(null, ex.getMessage());
                } finally {
                    out.close();
                    JOptionPane.showMessageDialog(null, "Save done");
                }
            }
        }

    }//GEN-LAST:event_saveButtonActionPerformed

    private ArrayList<String> getURLList() {
        ArrayList<String> list = new ArrayList<String>();
        int rowCount = uploadTableModel.getRowCount();
        if (rowCount > 0) {
            for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
                /* check status: column 4 */
                String status = (String) uploadTableModel.getValueAt(rowIndex, 3);
                if (status.equals("Done")) {
                    list.add((String) uploadTableModel.getValueAt(rowIndex, 1));
                }
            }
        }
        return list;
    }

    /**
     * subdomain=api.photobucket.com
     * requestPath=/login/request
     * method=POST
     * oauth_consumer and oauth_consumer_secret get from Bundle consumer
     *
     * Response: oauth_token and oauth_token_secret for consumer
     */
    private void request() {
        PhotobucketAPI api = new PhotobucketAPI();
        api.setSubdomain("api.photobucket.com");
        api.setRequestPath("/login/request");
        api.setMethod("POST");
        api.setOauthConsumerKey(this.oauth_consumer);
        api.setOauthConsumerSecret(this.oauth_consumer_key);

        try {
            RESTfulResponse r = api.execute();
            consumerMap = Utils.getTokenRespone(r.getResponseString());
            resultArea.setText("http://photobucket.com/apilogin/login?oauth_token="
                    + consumerMap.get("oauth_token"));
        } catch (Exception e) {
            resultArea.setText(e.getMessage());
        }
    }

    /**
     * subdomain=api.photobucket.com
     * requestPath=/login/access
     * method=POST
     * oauth_consumer and oauth_consumer_secret are added in request() method
     * oauth_token and oauth_token_secret get from request() method
     *
     * Response: oauth_token and oauth_token_secret for user (not consumer)
     * username, subdomain and homeurl (is encoded)
     */
    private void access() {
        resultArea.setText("");
        PhotobucketAPI api = new PhotobucketAPI();
        api.setSubdomain("api.photobucket.com");
        api.setOauthConsumerKey(this.oauth_consumer);
        api.setOauthConsumerSecret(this.oauth_consumer_key);
        api.setMethod("POST");
        api.setRequestPath("/login/access");
        api.setOauthToken(consumerMap.get("oauth_token"));
        api.setOauthTokenSecret(consumerMap.get("oauth_token_secret"));

        try {
            RESTfulResponse r = api.execute();
            userMap = Utils.getTokenRespone(r.getResponseString());
        } catch (Exception e) {
            resultArea.setText(e.getMessage());
        }
    }

    /**
     * subdomain=apiXXX.photobucket.com get from access() method
     * requestPath=/user/user_name
     * method=GET
     * oauth_consumer and oauth_consumer_key get from bundle consumer
     * User's oauth_token and oauth_token_secret get from access() method
     */
    private void getUserInfo() {
        PhotobucketAPI api = new PhotobucketAPI();
        api.setSubdomain(userMap.get("subdomain"));
        api.setRequestPath("/user/" + userMap.get("username"));
        api.setMethod("GET");
        api.setOauthConsumerKey(this.oauth_consumer);
        api.setOauthConsumerSecret(this.oauth_consumer_key);
        api.setOauthToken(userMap.get("oauth_token"));
        api.setOauthTokenSecret(userMap.get("oauth_token_secret"));

        try {
            RESTfulResponse r = api.execute();
            resultArea.setText(r.getResponseString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * subdomain=apiXXX.photobucket.com get from access() method
     * requestPath=/album/album_name
     * method=GET
     * oauth_consumer and oauth_consumer_key get from bundle consumer
     * User's oauth_token and oauth_token_secret get from access() method
     *
     * Response: Album's information
     */
    private String getAlbumInfo() {
        PhotobucketAPI api = new PhotobucketAPI();
        api.setSubdomain(userMap.get("subdomain"));
        api.setRequestPath("/album/" + userMap.get("username"));
        api.setMethod("GET");
        api.setOauthConsumerKey(ResourceBundle.getBundle("consumer").getString("oauth.consumer"));
        api.setOauthConsumerSecret(ResourceBundle.getBundle("consumer").getString("oauth.consumer.key"));
        api.setOauthToken(userMap.get("oauth_token"));
        api.setOauthTokenSecret(userMap.get("oauth_token_secret"));
        Map<String, String> params = new HashMap<String, String>();
        params.put("recurse", "true");
        api.setParameters(params);

        try {
            RESTfulResponse r = api.execute();
            return r.getResponseString();
        } catch (Exception e) {
            return e.getMessage();
        }
    }

    /**
     * subdomain=apiXXX.photobucket.com
     * method=POST
     * requestPath=/album/Album_Name/upload
     */
    private String upload(String filePath, String albumName, int rowIndex) throws Exception {

        if (filePath.equals("")) {
            return "No file path to upload";
        } else {

            String albumNameEncode;
            try {
                albumNameEncode = URLEncoder.encode(albumName, "UTF-8");
            } catch (UnsupportedEncodingException ex) {
                albumNameEncode = albumName;
            }
            PhotobucketAPI api = new PhotobucketAPI();
            File imageFile = new File(filePath);
            String fileNameWithoutExtension = Utils.getFileNameWithoutExtension(imageFile.getName());
            Map<String, String> params = new HashMap<String, String>();
            params.put("title", fileNameWithoutExtension);
            params.put("type", "image");

            api.setSubdomain(userMap.get("subdomain"));
            api.setRequestPath("/album/" + albumNameEncode + "/upload");
            api.setMethod("POST");
            api.setOauthConsumerKey(this.oauth_consumer);
            api.setOauthConsumerSecret(this.oauth_consumer_key);
            api.setOauthToken(userMap.get("oauth_token"));
            api.setOauthTokenSecret(userMap.get("oauth_token_secret"));
            api.setParameters(params);
            api.setUploadFile(imageFile);
            api.setUploadFileName(fileNameWithoutExtension);
            api.addFileUploadProgressEventListener(new FileUploadProgress(rowIndex));

            System.out.println("upload file:" + filePath);
            RESTfulResponse r = api.execute();
            return r.getResponseString();
        }
    }

    private void updateAlbumsMap(String albumName, int countSuccess) {
        HashMap<String, String> tmp = albumsMap.get(albumName);
        int photo_count = Integer.valueOf(tmp.get("photo_count"));
        int new_photo_count = photo_count + countSuccess;
        tmp.put("photo_count", Integer.toString(new_photo_count));
        albumsMap.put(albumName, tmp);
        numberTextField.setText(Integer.toString(new_photo_count));
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new UploadPhotobucket().setVisible(true);
            }
        });
    }

    class UploadWorker extends SwingWorker<Void, Void> {

        public UploadWorker() {
            super();
        }

        public UploadWorker(String albumName) {
            super();
            this.albumName = albumName;
        }

        @Override
        protected Void doInBackground() throws Exception {
            setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));

            int rowCount = uploadTableModel.getRowCount();
            for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
                String statusFile = (String) uploadTableModel.getValueAt(rowIndex, 3);
                if (!statusFile.equals("Done")) {
                    String filePath = uploadTableModel.getValueAt(rowIndex, 0).toString();
                    String response = upload(filePath, albumName, rowIndex);
                    System.out.println("uploaded");
                    String status = Utils.getFromTag(response, "status");
                    if (status.equals("OK")) {
                        //upload successful
                        countSuccess++;
                        String url = Utils.getFromTag(response, "url");
                        String linkBlog = "[IMG]" + url + "[/IMG]";
                        // update url to table
                        uploadTableModel.setValueAt(url, rowIndex, 1);
                        // update link blog to table
                        uploadTableModel.setValueAt(linkBlog, rowIndex, 2);
                        // update status to table
                        uploadTableModel.setValueAt("Done", rowIndex, 3);
                    } else {
                        uploadTableModel.setValueAt("Failed", rowIndex, 3);
                    }
                }

                if (countSuccess > 0) {
                    updateAlbumsMap(albumName, countSuccess);
                }
            }
            JOptionPane.showMessageDialog(null, "Upload done");
            return null;
        }

        @Override
        protected void done() {
            setCursor(null);
        }
        private String albumName;
    }

    class FileUploadProgress implements IFileUploadProgressEventListener {

        public FileUploadProgress() {
        }

        public FileUploadProgress(int rowIndex) {
            this.rowIndex = rowIndex;
        }

        public void fileUploadProgressUpdate(FileUploadProgressEvent fupe) {
            uploadTableModel.setValueAt(fupe.getPercentComplete() + "%", rowIndex, 3);
        }
        private int rowIndex;
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel aboutPanel;
    private javax.swing.JButton accessButton;
    private javax.swing.JButton addButton;
    private javax.swing.JComboBox albumComboBox;
    private javax.swing.JButton clearButton;
    private javax.swing.JButton copyLinkBlogButton;
    private javax.swing.JButton copyLinkURLButton;
    private javax.swing.JButton getReqButton;
    private javax.swing.JButton goButton;
    private javax.swing.JPanel howToUsePanel;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JLabel jLabel13;
    private javax.swing.JLabel jLabel14;
    private javax.swing.JLabel jLabel15;
    private javax.swing.JLabel jLabel16;
    private javax.swing.JLabel jLabel17;
    private javax.swing.JLabel jLabel18;
    private javax.swing.JLabel jLabel19;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel20;
    private javax.swing.JLabel jLabel21;
    private javax.swing.JLabel jLabel22;
    private javax.swing.JLabel jLabel23;
    private javax.swing.JLabel jLabel24;
    private javax.swing.JLabel jLabel25;
    private javax.swing.JLabel jLabel26;
    private javax.swing.JLabel jLabel27;
    private javax.swing.JLabel jLabel28;
    private javax.swing.JLabel jLabel29;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JTabbedPane jTabbedPane1;
    private javax.swing.JPanel loginPanel;
    private javax.swing.JTextField numberTextField;
    private javax.swing.JButton removeButton;
    private javax.swing.JTextArea resultArea;
    private javax.swing.JButton saveButton;
    private javax.swing.JButton showImageButton;
    private javax.swing.JButton uploadButton;
    private javax.swing.JPanel uploadPanel;
    private javax.swing.JTable uploadTable;
    // End of variables declaration//GEN-END:variables
    private Map<String, String> userMap;
    private Map<String, String> consumerMap;
    private String oauth_consumer;
    private String oauth_consumer_key;
    private DefaultTableModel uploadTableModel;
    private Vector dataUpload;
    private Vector columnUpload;
    private String browser;
    private DefaultComboBoxModel comboBoxModel;
    private Map<String, HashMap<String, String>> albumsMap;
    private int countSuccess;
    private UploadWorker worker;
    private String currentPath;
}
